package tjs.study.notes.dotest.jvm.thread;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import tjs.study.notes.base.common.ThreadUtils;

import java.util.*;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicReference;

/**
 * Created by Nicky.Tang on 2023/11/27 10:00
 *
 * @since 02.12.10
 */
public class 测试可见性2 {
    private static final Logger logger = LoggerFactory.getLogger(测试可见性2.class);
    public static int serviceNum = 1;


    public static void main(String[] args) throws InterruptedException {
        ExecutorService executorService = Executors.newFixedThreadPool(20);
        AtomicReference<List<Integer>> res = new AtomicReference<>(new ArrayList<>());
        for (Integer i = 0; i < 200; i++) {
            Integer finalI = i;
            executorService.submit(() -> {
                synchronized (res) {
                    // copy-on-write机制，直接替换引用，读取时不需要new ArrayList复制一份，也能正常运行
                    // List<Integer> resCopy = new ArrayList<>(res.get());
                    // resCopy.add(finalI);
                    // res.set(resCopy);
                    
                    res.get().add(finalI);

                    logger.info("追加实例：{}", finalI);
                    ThreadUtils.sleepMilliSeconds(10);
                }
            });
        }

        new Thread(() -> {
            while (true) {
                StringBuilder stringBuilder = new StringBuilder();
                Iterator<Integer> resIte = res.get().iterator(); // 触发fast-fail。这种写法，写入时不使用COW机制，会报错java.util.ArrayList.Itr.checkForComodification
                // Iterator<Integer> resIte = new ArrayList<>(res.get()).iterator();// 复制一份，即使原List发生变更，也不会报错
                while (resIte.hasNext()) {
                    Integer re = resIte.next();
                    stringBuilder.append(re).append(",");
                }
                logger.info("{} 可见实例：{}", res.get().size(), stringBuilder);
            }
        }).run();
        executorService.awaitTermination(9999, TimeUnit.MINUTES);
    }

}
